using System;
using System.Collections.Generic;
using System.Text;

namespace Nua.Runtime
{
	public class NuaTable : IDictionary<object, object>
	{
		internal readonly Dictionary<object, object> data;
		internal readonly ICollection<KeyValuePair<object, object>> collection;

		public NuaTable MetaTable;

		public NuaTable()
		{
			data = new Dictionary<object, object>();
			collection = data;
		}

		public void Add(object key, object value)
		{
			data.Add(key, value);
		}

		public bool ContainsKey(object key)
		{
			return data.ContainsKey(key);
		}

		public ICollection<object> Keys
		{
			get
			{
				return data.Keys;
			}
		}

		public bool Remove(object key)
		{
			return data.Remove(key);
		}

		public ICollection<object> Values
		{
			get
			{
				return data.Values;
			}
		}

		public object this[object key]
		{
			get
			{
				if (!data.ContainsKey(key))
					return null;

				return data[key];
			}

			set
			{
				data[key] = value;
			}
		}

		public void Add(KeyValuePair<object, object> item)
		{
			collection.Add(item);
		}

		public void Clear()
		{
			data.Clear();
		}

		public bool Contains(KeyValuePair<object, object> item)
		{
			return collection.Contains(item);
		}

		public void CopyTo(KeyValuePair<object, object>[] array, int arrayIndex)
		{
			collection.CopyTo(array, arrayIndex);
		}
		public int Count
		{
			get
			{
				return data.Count;
			}
		}

		public bool IsReadOnly
		{
			get
			{
				return collection.IsReadOnly;
			}
		}

		public bool Remove(KeyValuePair<object, object> item)
		{
			return collection.Remove(item);
		}

		public IEnumerator<KeyValuePair<object, object>> GetEnumerator()
		{
			return collection.GetEnumerator();
		}

        bool System.Collections.Generic.IDictionary<object, object>.TryGetValue(object key, out object value)
		{
			if (!data.TryGetValue(key, out value))
			{
				value = null;
			}

			// TryGetValue always succeeds-- any key not in the
			// collection maps to null. See the implementation of
			// this[] above.
			return true;
		}

		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			// TODO: This collection is 'infinite', with any
			// key not in the underlying collection mapping to
			// 'null'. (See the implementation of this[] above.)
			// So enumerating the collection can't be supported
			// properly.
			throw new System.NotSupportedException();
			// return data.GetEnumerator();
		}

        public override string ToString()
		{
			return "table: " + this.GetHashCode();
		}
	}
}
